# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: helpers\licensing\erp\__init__.py
__author__ = "Attila Gerendi (Sanyi)"
import json, logging, requests, datetime, pytz
from dateutil.tz import tzlocal
from dateutil.relativedelta import relativedelta
from helpers.licensing.erp.errors import ErrorErp, ErrorErpParsing
from db.tables.licenses import LicenseStatus
from helpers.setup_types import *
from helpers.licensing.features import (
    is_on_premise_v12_product_code,
    is_ovs_product_code,
)

_logger = logging.getLogger("helpers.licensing.erp")
license_data_model = dict(
    status=LicenseStatus.OK,
    product_code=None,
    licenses=0,
    validity_start=None,
    expires=None,
    first_activated=None,
)


def get_module_by_name(license_data, module_name):
    for m in license_data["Modules"]:
        if m["ModuleCode"] == module_name:
            return m


def parse_erp_time(value):
    timestamp = int(value[6:16])
    offset = int(value[20:22]) * 60 + int(value[23:24]) * (
        1 if value[19] == "+" else -1
    )
    return datetime.datetime.fromtimestamp(timestamp, tz=pytz.FixedOffset(offset))


def parse_erp_data(data):
    """
    for now this function is only intended for use with/on online
    :param data:
    :return:
    """
    result = dict(license_data_model)
    result["data"] = data
    if not data["AlreadyActivated"]:
        result["status"] = LicenseStatus.NOT_ACTIVATED
    else:
        result["first_activated"] = parse_erp_time(
            data.get("FirstActivated", "/Date(0000000000000+0000)/")
        )
        result["validity_start"] = result["first_activated"]
    now = datetime.datetime.now(tz=tzlocal())
    result["product_code"] = data["ProductCode"]
    if is_setup_type_aws():
        if not is_ovs_product_code(result["product_code"]):
            result["status"] = LicenseStatus.INVALID_PC
            return result
    else:
        if is_setup_type_on_premise():
            if not is_on_premise_v12_product_code(result["product_code"]):
                result["status"] = LicenseStatus.INVALID_PC
                return result
        main = get_module_by_name(data, "MAIN")
        if main is None:
            result["status"] = LicenseStatus.NO_MAIN_MODULE
        if main["CanExpire"]:
            if main["ExpiryDate"] is not None:
                result["expires"] = parse_erp_time(main["ExpiryDate"])
        if main["Expired"]:
            result["status"] = LicenseStatus.EXPIRED
        if main["Licensing"][0]["Unlimited"] is True:
            result["licenses"] = 1000
        else:
            result["licenses"] = main["Licensing"][0]["Licenses"]
        if result["first_activated"]:
            for i in range(1, 20):
                d = result["first_activated"] + i * (relativedelta(years=1))
                if d > now or d > result["expires"]:
                    result["validity_start"] = result["first_activated"] + (i - 1) * (
                        relativedelta(years=1)
                    )
                    break

        return result


def erp_request(erp_url, data, readonly=True, timeout=5):
    rec = requests.Request(
        "POST",
        erp_url + "api/key/activate?readonly=" + ("true" if readonly else "false"),
        data=json.dumps(data),
        headers={"Content-Type": "application/json"},
    )
    prepared_rec = rec.prepare()
    s = requests.Session()
    resp = s.send(prepared_rec, timeout=timeout)
    if resp.status_code == 200:
        try:
            resp_data = resp.json()
        except Exception:
            raise ErrorErp("invalid data")

        try:
            return parse_erp_data(resp_data)
        except Exception as e:
            _logger.error("erp response parse failed with %s", e)
            raise ErrorErpParsing(str(e))

    else:
        if resp.status_code == 401:
            result = dict(license_data_model)
            result["status"] = LicenseStatus.UNAUTHORIZED
            return result
        if resp.status_code == 404:
            result = dict(license_data_model)
            result["status"] = LicenseStatus.NOT_FOUND
            return result
        raise ErrorErp("status code %s", resp.status_code)


def activate_license(erp_url, license_key, user_data):
    request_data = dict(LicenseKey=license_key, Email=user_data["email"])
    contact_name = []
    if user_data["first_name"]:
        contact_name.append(user_data["first_name"])
    if user_data["last_name"]:
        contact_name.append(user_data["last_name"])
    if contact_name:
        request_data["ContactName"] = (" ").join(contact_name)
    if user_data["phone"]:
        request_data["Telephone"] = user_data["phone"]
    if user_data["country"]:
        request_data["CountryID"] = user_data["country"]
    request_data["ProductMajorVer"] = 1
    return erp_request(erp_url, request_data, readonly=False)


def fetch_license(erp_url, license_key):
    return erp_request(erp_url, dict(LicenseKey=license_key), readonly=True)
